﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DynORM.Interfaces;
using DynORM.Mappers;
using DynORM.Enums;
using DynORM;
using DynORM.ValueObjects;
using DynORM.ReferenceObjects;
using System.Xml.Serialization;
using System.Xml;
using System.IO;

namespace UnitTests.DAL
{
    [TestClass]
    public class RowDescriptorSerializationUnitTests
    {
        private RowDescriptor GenerateNewRowDescriptor(string tableName)
        {
            Dictionary<int, IFieldDescriptor> pkFieldDescs = new Dictionary<int, IFieldDescriptor>();
            pkFieldDescs.Add(0, new FieldDescriptor(typeof(Guid), "RowID"));
            PrimaryKeyDescriptor pkd = new PrimaryKeyDescriptor(tableName, pkFieldDescs, tableName + "_PK");
            List<FieldDescriptor> fieldDescs = new List<FieldDescriptor>();
            fieldDescs.Add(new FieldDescriptor(typeof(string), "TestColumn"));
            return new RowDescriptor(tableName, fieldDescs, new List<IRelationDescriptor>() { pkd });
        }

        private string XmlXPathRunner(string xml, string xpath)
        {
            //intencially use XPath here in order to make this test independed from formatters
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            //XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            //nsmgr.AddNamespace("ns", "http://schemas.datacontract.org/2004/07/IEOServerJobWebAPI.Auxiliary");
            //nsmgr.AddNamespace("i", "http://www.w3.org/2001/XMLSchema-instance");

            //XmlNode node = doc.SelectSingleNode(xpath, nsmgr);
            XmlNode node = doc.SelectSingleNode(xpath);

            return node.InnerText;
        }


        [TestMethod]
        public void SerializeRowDescriptorTest()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlTextWriter writer = new XmlTextWriter(ms, UTF8Encoding.Default);

                XmlSerializer formatter = new XmlSerializer(typeof(RowDescriptor));
                RowDescriptor rd = GenerateNewRowDescriptor("TestTableName");
                formatter.Serialize(writer, rd);

                ms.Position = 0;
                StreamReader sr = new StreamReader(ms);
                string xml = sr.ReadToEnd();
            }
            //Assert.AreEqual(xml, @"");
        }

        [TestMethod]
        public void DeserializeRowDescriptorTest()
        {
            RowDescriptor rd;
            using (MemoryStream ms = new MemoryStream())
            {
                XmlTextWriter writer = new XmlTextWriter(ms, UTF8Encoding.Default);

                XmlSerializer formatter = new XmlSerializer(typeof(RowDescriptor));
                rd = GenerateNewRowDescriptor("TestTableName");
                formatter.Serialize(writer, rd);

                ms.Position = 0;
                XmlTextReader reader = new XmlTextReader(ms);
                rd = (RowDescriptor)formatter.Deserialize(reader);
            }

            Assert.AreEqual("TestTableName", rd.TableName);
            Assert.AreEqual("RowID", rd.PrimaryKeyDescriptor.FieldDescriptors.First<KeyValuePair<int, IFieldDescriptor>>().Value.FieldName);
            Assert.AreEqual("TestColumn", rd.FieldDescriptors.First<IFieldDescriptor>().FieldName);
        }

        private RowDescriptor GenerateNewRowDescriptor2(string tableName)
        {
            Dictionary<int, IFieldDescriptor> pkFieldDescs = new Dictionary<int, IFieldDescriptor>();
            pkFieldDescs.Add(0, new FieldDescriptor(typeof(Guid), "RowID"));
            PrimaryKeyDescriptor pkd = new PrimaryKeyDescriptor(tableName, pkFieldDescs, tableName + "_PK");
            List<IRelationDescriptor> pkds = new List<IRelationDescriptor>() { pkd };

            List<FieldDescriptor> fieldDescs = new List<FieldDescriptor>();
            fieldDescs.Add(new FieldDescriptor(typeof(string), "TestColumn"));

            List<IRelationDescriptor> fkds = new List<IRelationDescriptor>();
            Dictionary<int, IFieldDescriptor> fkFieldDescs = new Dictionary<int, IFieldDescriptor>();
            fkFieldDescs.Add(0, new FieldDescriptor(typeof(Guid), "ForeignRowID"));
            ForeignKeyDescriptor fkd = new ForeignKeyDescriptor(tableName, fkFieldDescs, tableName, pkFieldDescs, tableName + "_" + tableName + "_FK");
            fkds.Add(fkd);

            Dictionary<int, IFieldDescriptor> fkFieldDescs2 = new Dictionary<int, IFieldDescriptor>();
            fkFieldDescs2.Add(0, new FieldDescriptor(typeof(Guid), "ForeignRowID_1"));
            ForeignKeyDescriptor fkd2 = new ForeignKeyDescriptor(tableName, fkFieldDescs2, tableName, pkFieldDescs, tableName + "_" + tableName + "_FK");
            fkds.Add(fkd2);
            return new RowDescriptor(tableName, fieldDescs, pkds.Union(fkds));
        }

        [TestMethod]
        public void SerializeRowDescriptorTest2()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlTextWriter writer = new XmlTextWriter(ms, UTF8Encoding.Default);

                XmlSerializer formatter = new XmlSerializer(typeof(RowDescriptor));
                RowDescriptor rd = GenerateNewRowDescriptor2("TestTableName");
                formatter.Serialize(writer, rd);

                ms.Position = 0;
                StreamReader sr = new StreamReader(ms);
                string xml = sr.ReadToEnd();
            }
            //Assert.AreEqual(xml, @"");
        }

        [TestMethod]
        public void DeserializeRowDescriptorTest2()
        {
            RowDescriptor rd;
            using (MemoryStream ms = new MemoryStream())
            {
                XmlTextWriter writer = new XmlTextWriter(ms, UTF8Encoding.Default);

                XmlSerializer formatter = new XmlSerializer(typeof(RowDescriptor));
                rd = GenerateNewRowDescriptor2("TestTableName");
                formatter.Serialize(writer, rd);

                ms.Position = 0;
                XmlTextReader reader = new XmlTextReader(ms);
                rd = (RowDescriptor)formatter.Deserialize(reader);
            }

            Assert.AreEqual("TestTableName", rd.TableName);
            Assert.AreEqual("RowID", rd.PrimaryKeyDescriptor.FieldDescriptors.First<KeyValuePair<int, IFieldDescriptor>>().Value.FieldName);
            Assert.AreEqual("TestColumn", rd.FieldDescriptors.First<IFieldDescriptor>().FieldName);
        }
    }
}
